﻿using OfficeOpenXml;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Reflection;

namespace Core
{
    public static class EPPlusExtension
    {
        /// <summary>
        /// 获取标签对应excel的Index
        /// </summary>
        public static int GetColumnByName(this ExcelWorksheet ws, string columnName)
        {
            if (ws == null) throw new ArgumentNullException(nameof(ws));
            return ws.Cells["1:1"].First(c => c.Value.ToString() == columnName).Start.Column;
        }

        /// <summary>
        /// 扩展方法
        /// </summary>
        public static IEnumerable<T> ConvertSheetToObjects<T>(this ExcelWorksheet worksheet) where T : new()
        {
            Func<CustomAttributeData, bool> columnOnly = y => y.AttributeType == typeof(ColumnAttribute);
            var columns = typeof(T).GetProperties().Where(x => x.CustomAttributes.Any(columnOnly)).Select(p => new
            {
                Property = p,
                Column = p.GetCustomAttributes<ColumnAttribute>().First().Name
            }).ToList();

            var rows = worksheet.Cells.Select(cell => cell.Start.Row).Distinct().OrderBy(x => x);

            var collection = rows.Skip(1).Select(row =>
            {
                var TNew = new T();
                columns.ForEach(col =>
                {
                    var cell = worksheet.Cells[row, GetColumnByName(worksheet, col.Column)];
                    if (cell.Value == null)
                    {
                        col.Property.SetValue(TNew, null);
                        return;
                    }
                    else if (col.Property.PropertyType == typeof(int))
                    {
                        col.Property.SetValue(TNew, cell.GetValue<int>());
                        return;
                    }
                    else if (col.Property.PropertyType == typeof(long))
                    {
                        col.Property.SetValue(TNew, cell.GetValue<int>());
                        return;
                    }
                    else if (col.Property.PropertyType == typeof(decimal))
                    {
                        col.Property.SetValue(TNew, cell.GetValue<decimal>());
                        return;
                    }
                    else if (col.Property.PropertyType == typeof(DateTime?))
                    {
                        col.Property.SetValue(TNew, cell.GetValue<DateTime?>());
                        return;
                    }
                    else if (col.Property.PropertyType == typeof(DateTime))
                    {
                        col.Property.SetValue(TNew, cell.GetValue<DateTime>());
                        return;
                    }
                    else if (col.Property.PropertyType == typeof(bool))
                    {
                        col.Property.SetValue(TNew, cell.GetValue<bool>());
                        return;
                    }

                    col.Property.SetValue(TNew, cell.GetValue<string>());
                });

                return TNew;
            });

            return collection;
        }
    }
}